package com.spzx.product.service.impl;


import cn.hutool.core.date.DateTime;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.domain.Category;
import com.spzx.product.handler.CategoryExcelListener;
import com.spzx.product.mapper.CategoryMapper;
import com.spzx.product.service.CategoryService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Override
    public List<Category> listByPid(Long pid) {

        List<Category> categories = this.list(Wrappers.lambdaQuery(Category.class)
                .eq(Category::getParentId, pid).orderByDesc(Category::getOrderNum));

        if (!CollectionUtils.isEmpty(categories)) {
            categories.forEach(category -> {

                long count = this.count(Wrappers.lambdaQuery(Category.class).eq(Category::getParentId, category.getId()));
                category.setHasChildren(count > 0);

            });

        }

        return categories;
    }

    @Override
    public List<Long> selectCategoryIdsByC3Id(Long category3Id) {
        String cIds = baseMapper.selectCategoryIdsByC3Id(category3Id);
        List<Long> idList = Arrays.stream(cIds.split(","))
                .toList().stream().map(s -> Long.parseLong(s)).collect(Collectors.toList());
        return idList;
    }

    @Override
    public int importCates(MultipartFile file) {
        try {
            //1、文件校验：文件大小(必须大于0)和名称校验(扩展名必须为xlsx、xls、csv)
            InputStream is = file.getInputStream();
            if (is.available() == 0) {
                throw new ServiceException("上传文件大小异常");

            }
            String filename = file.getOriginalFilename().toLowerCase();
            if (!filename.endsWith(".xlsx") && !filename.endsWith(".xls") && !filename.endsWith(".csv")) {
                throw new ServiceException("上传文件格式错误");
            }
            //2、使用EasyExcel读取excel文件
            EasyExcel.read(is).head(Category.class)
                    .registerReadListener(new CategoryExcelListener(this))
                    .sheet(0)
                    .doRead();
            return 1;
        } catch (IOException e) {
            throw new ServiceException(e.getMessage());
        }

    }

    @Override
    public void exportCates(HttpServletResponse response) {
        try {
            //1、查询所有分类
            List<Category> categoryList = this.list();
            //2、： 响应报文头需要配置(告诉浏览器下载文件的名称 以及文件格式 )
            //Http协议的报文不允许传递非ISO8859-1编码的字符，可以通过UrlEncoder将中文转为unicode编码来传递
            String fileName = URLEncoder.encode("分类列表_" +
                    new DateTime().toString("yyyy年MM月dd日HH时mm分ss秒")
                    + ExcelTypeEnum.XLSX.getValue(), "UTF-8");
            response.setHeader("content-disposition", "attachment;filename=" + fileName);
            //3、将所有分类写入到excel文件：  通过EasyExcel注解让excel列和分类的属性形成映射
            EasyExcel.write(response.getOutputStream())//将上面的excel文件写入到响应体
                    .sheet("分类数据")
                    .head(Category.class)
                    .doWrite(categoryList);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean categoryExists(Category data) {

        LambdaQueryWrapper<Category> lambdaQuery = Wrappers.lambdaQuery(Category.class);
        // LambdaQueryWrapper : 默认使用 and 阻止拼接
        lambdaQuery.eq(Category::getId, data.getId());
        lambdaQuery.or(q -> q.eq(Category::getParentId, data
                .getParentId()).eq(Category::getName, data.getName()));

        return this.count(lambdaQuery) > 0;
    }

    @Override
    public List<Category> listCateTree() {
        //1、查询所有分类
        List<Category> categories = this.list();
        if(CollectionUtils.isEmpty(categories)){
            return null;
        }
        //2、递归组装分类数据
        //挑选一级分类集合
        List<Category> levelOneCates = categories.stream().filter(category -> category.getParentId().longValue() == 0L)
                .collect(Collectors.toList());
        buildCateTree(levelOneCates,categories);
        return levelOneCates;
    }

    private void buildCateTree(List<Category> parents, List<Category> categories) {
        if(CollectionUtils.isEmpty(parents) || CollectionUtils.isEmpty(categories)){
            return;
        }
        parents.forEach(parent->{
            //获取正在遍历的父分类的下一级
            List<Category> children = categories.stream().filter(category -> category.getParentId().longValue() == parent.getId().longValue())
                    .collect(Collectors.toList());
            //将上面查询到的下一级分类集合设置给父分类
            if(!CollectionUtils.isEmpty(children)){
                parent.setChildren(children);
                buildCateTree(children , categories);
            }

        });
    }

}
